package com.suncreate.radarscan.model;


import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;


//多边形
public class Polygon {
	private String lineColor;
	private boolean isLegal;
	private int level;//优先级，数字越大优先级越高1-9
	private String name;//名称
	private List<Point2D.Double> points;//多边形的顶点
	

	public String getLineColor() {
		return lineColor;
	}


	public void setLineColor(String lineColor) {
		this.lineColor = lineColor;
	}


	public boolean isLegal() {
		return isLegal;
	}


	public void setLegal(boolean isLegal) {
		this.isLegal = isLegal;
	}


	public int getLevel() {
		return level;
	}


	public void setLevel(int level) {
		this.level = level;
	}


	public String getName() {
		return name;
	}


	public void setName(String name) {
		this.name = name;
	}


	public List<Point2D.Double> getPoints() {
		return points;
	}


	public void setPoints(List<Point2D.Double> points) {
		this.points = points;
	}


	/**
	 * 
	 * @Description: 判断点是否在多边形内部 
	 * @param  point 检测点
	 * @return boolean 点在多边形内返回true,否则返回false 
	 */
    public boolean IsPointIn(Point2D.Double point){
    	int N = this.points.size();
        boolean boundOrVertex = true; //如果点位于多边形的顶点或边上，也算做点在多边形内，直接返回true
        int intersectCount = 0;//cross points count of x 
        double precision = 2e-10; //浮点类型计算时候与0比较时候的容差
        Point2D.Double p1, p2;//neighbour bound vertices
        Point2D.Double p = point; //当前点
        
        p1 = this.points.get(0);//left vertex        
        for(int i = 1; i <= N; ++i){//check all rays            
            if(p.equals(p1)){
                return boundOrVertex;//p is an vertex
            }
            
            p2 = this.points.get(i % N);//right vertex            
            if(p.x < Math.min(p1.x, p2.x) || p.x > Math.max(p1.x, p2.x)){//ray is outside of our interests                
                p1 = p2; 
                continue;//next ray left point
            }
            
            if(p.x > Math.min(p1.x, p2.x) && p.x < Math.max(p1.x, p2.x)){//ray is crossing over by the algorithm (common part of)
                if(p.y <= Math.max(p1.y, p2.y)){//x is before of ray                    
                    if(p1.x == p2.x && p.y >= Math.min(p1.y, p2.y)){//overlies on a horizontal ray
                        return boundOrVertex;
                    }
                    
                    if(p1.y == p2.y){//ray is vertical                        
                        if(p1.y == p.y){//overlies on a vertical ray
                            return boundOrVertex;
                        }else{//before ray
                            ++intersectCount;
                        } 
                    }else{//cross point on the left side                        
                        double xinters = (p.x - p1.x) * (p2.y - p1.y) / (p2.x - p1.x) + p1.y;//cross point of y                        
                        if(Math.abs(p.y - xinters) < precision){//overlies on a ray
                            return boundOrVertex;
                        }
                        
                        if(p.y < xinters){//before ray
                            ++intersectCount;
                        } 
                    }
                }
            }else{//special case when ray is crossing through the vertex                
                if(p.x == p2.x && p.y <= p2.y){//p crossing over p2                    
                    Point2D.Double p3 = this.points.get((i+1) % N); //next vertex                    
                    if(p.x >= Math.min(p1.x, p3.x) && p.x <= Math.max(p1.x, p3.x)){//p.x lies between p1.x & p3.x
                        ++intersectCount;
                    }else{
                        intersectCount += 2;
                    }
                }
            }            
            p1 = p2;//next ray left point
        }
        
        if(intersectCount % 2 == 0){//偶数在多边形外
            return false;
        } else { //奇数在多边形内
            return true;
        }
    }
	/*
	 * C#写法
	public class Polygon
    {
        private string _name = "";
        public Color LineColor = Color.LightGreen;//颜色
        public string Name//名称
        {
            get
            {
                return _name;
            }
            set 
            {
                _name = value;
            }
        }
        public bool IsLegal = true;
        public int Level = 1;//优先级，数字越大优先级越高1-9

        private List<PointD> _points = new List<PointD>();//多边形点集合，自动会将首尾相连
        public List<PointD> Points
        {
            get { return _points; }
        }
        //判断点是否在多边形内部
        public bool IsPointIn(PointD point)
        {
            int i, j = _points.Count - 1;
            bool oddNodes = false;
            for (i = 0; i < _points.Count; i++)
            {
                if ((_points[i].Y < point.Y && _points[j].Y >= point.Y
                || _points[j].Y < point.Y && _points[i].Y >= point.Y)
                && (_points[i].X <= point.X || _points[j].X <= point.X))
                {
                    oddNodes ^= (_points[i].X + (point.Y - _points[i].Y) / (_points[j].Y - _points[i].Y) * (_points[j].X - _points[i].X) < point.X);
                }
                j = i;
            }

            return oddNodes;
        }
    }
	 */
}
